﻿using System;
using System.Text.RegularExpressions;

namespace Jerkymon.Numeric
{
    public class Utility
    {
		#region Static Methods (11)
		public static long Fix(double Number)
        {
            if (Number >= 0)
            {
                return (long)Math.Floor(Number);
            }
            return (long)Math.Ceiling(Number);
        }

		// Function to Test for Integers both Positive & Negative
        public static bool IsInteger(String strNumber)
        {
            Regex objNotIntPattern = new Regex("[^0-9-]");
            Regex objIntPattern = new Regex("^-[0-9]+$|^[0-9]+$");
            return !objNotIntPattern.IsMatch(strNumber) && objIntPattern.IsMatch(strNumber);
        }

		// Function to test for Positive Integers.
        public static bool IsNaturalNumber(String strNumber)
        {
            Regex objNotNaturalPattern = new Regex("[^0-9]");
            Regex objNaturalPattern = new Regex("0*[1-9][0-9]*");
            return !objNotNaturalPattern.IsMatch(strNumber) &&
            objNaturalPattern.IsMatch(strNumber);
        }

		// Function to test whether the string is valid number or not
        public static bool IsNumber(String strNumber)
        {
            Regex objNotNumberPattern = new Regex("[^0-9.-]");
            Regex objTwoDotPattern = new Regex("[0-9]*[.][0-9]*[.][0-9]*");
            Regex objTwoMinusPattern = new Regex("[0-9]*[-][0-9]*[-][0-9]*");
            String strValidRealPattern = "^([-]|[.]|[-.]|[0-9])[0-9]*[.]*[0-9]+$";
            String strValidIntegerPattern = "^([-]|[0-9])[0-9]*$";
            Regex objNumberPattern = new Regex("(" + strValidRealPattern + ")|(" + strValidIntegerPattern + ")");
            return !objNotNumberPattern.IsMatch(strNumber) &&
            !objTwoDotPattern.IsMatch(strNumber) &&
            !objTwoMinusPattern.IsMatch(strNumber) &&
            objNumberPattern.IsMatch(strNumber);
        }

		// Function to Test for Positive Number both Integer & Real
        public static bool IsPositiveNumber(String strNumber)
        {
            Regex objNotPositivePattern = new Regex("[^0-9.]");
            Regex objPositivePattern = new Regex("^[.][0-9]+$|[0-9]*[.]*[0-9]+$");
            Regex objTwoDotPattern = new Regex("[0-9]*[.][0-9]*[.][0-9]*");
            return !objNotPositivePattern.IsMatch(strNumber) &&
            objPositivePattern.IsMatch(strNumber) &&
            !objTwoDotPattern.IsMatch(strNumber);
        }

		// Function to test for Positive Integers with zero inclusive
        public static bool IsWholeNumber(String strNumber)
        {
            Regex objNotWholePattern = new Regex("[^0-9]");
            return !objNotWholePattern.IsMatch(strNumber);
        }

		public static int RandomNumber(int min, int max)
        {
            //	byte[] randbyte = new byte[0];
            //	RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            //	rng.GetNonZeroBytes(randbyte);
            //	Random rand = new Random(Convert.ToInt32(randbyte[0]));
            //	return rand.Next(min, max);

            Random R = new Random();
            int i = 0;
           
            for (min = 0; min < max; min++)
            {
                i = R.Next(max);
            }
            return i;
        }

		public static decimal Rounding(decimal numToRound, int numOfDec)
        {
            if (numOfDec < 0)
            {
                throw new ArgumentException("BetterMath.Rounding:" +
                    " Number of decimal places must be 0 or greater",
                    "numOfDec");
            }

            decimal num = numToRound;

            //Shift the decimal to the right the number 
            //of digits they want to round to
            for (int i = 1; i <= numOfDec; i++)
            {
                num *= 10;
            }

            //Add/Subtract .5 to TRY to increase the number 
            //that is to the LEFT of the decimal
            if (num < 0)
            {
                num -= .5M;
            }
            else
            {
                num += .5M;
            }

            //Cut off the decimal, you have your answer!
            num = (decimal)((int)num);

            //Shift the decimal back into its proper position
            for (int i = 1; i <= numOfDec; i++)
            {
                num /= 10;
            }

            return num;

        }

		public static float Rounding(float numToRound, int numOfDec)
        {
            return (float)Rounding((decimal)numToRound, numOfDec);
        }

		public static double Rounding(double numToRound, int numOfDec)
        {
            return (double)Rounding((decimal)numToRound, numOfDec);
        }

		public static string ToOrdinal(int num)
        {
            switch (num % 100)
            {
                case 11:
                case 12:
                case 13:
                    return num.ToString() + "th";
            }

            switch (num % 10)
            {
                case 1:
                    return num.ToString() + "st";
                case 2:
                    return num.ToString() + "nd";
                case 3:
                    return num.ToString() + "rd";
                default:
                    return num.ToString() + "th";
            }

        }
		#endregion
    }
}
